#include "threadPool.h"

int exitPipe[2];

void handler(int signum){          // 注册10号信号，用于退出服务端
    printf("signum = %d\n",signum);
    write(exitPipe[1],"1",1);
}

int main(int argc, char *argv[]){
    ARGS_CHECK(argc,4);            // IP，port，工人线程数
    pipe(exitPipe);                // 父子进程间通信
    if(fork()){                    // 父进程只检测信号，子进程做线程池
        close(exitPipe[0]);
        signal(SIGUSR1,handler);
        wait(NULL);
        printf("parent is going to exit,pid = %d\n",getpid());
        exit(0);
    }
    close(exitPipe[1]);
    threadPool_t threadPool;
    threadPoolInit(&threadPool,atoi(argv[3]));    // 初始化线程池结构体，传入工人线程数
    makeWorker(&threadPool);                      // 创建工人线程
    int sockfd = tcpInit(argv[1],argv[2]);        // 得到监听socket
    int epollfd = epoll_create(1);
    epollAdd(epollfd,sockfd);
    epollAdd(epollfd,exitPipe[0]);
    struct epoll_event readyset[1024];
    int netfd;
    int set_pointer;                              // 指向集合的指针，表示这一秒内就绪的fd要放入的集合
    timeout_t out;
    timeoutInit(&out);
    while(1){
        int readyNum = epoll_wait(epollfd,readyset,1024,1000); // 每隔1秒epoll至少会就绪一次
        set_pointer = time(NULL)%30;
        for(int i = 0;i < readyNum;i++){
            if(readyset[i].data.fd == sockfd){                 // 有新连接接入
                // 判断是新的客户端登录还是旧的客户端要puts或gets，根据是否有token
                // 新的客户端登录要加入监听
                netfd = accept(sockfd,NULL,NULL);
//                printf("main gets this job,netfd = %d\n", netfd);
//                pthread_mutex_lock(&threadPool.mutex);
//                enqueue(&threadPool.taskQueue,netfd);
//                pthread_cond_broadcast(&threadPool.cond);
//                pthread_mutex_unlock(&threadPool.mutex);
            }
            else if(readyset[i].data.fd == exitPipe[0]){       // 退出逻辑
                pthread_mutex_lock(&threadPool.mutex);
                threadPool.exitflag = 1;
                pthread_cond_broadcast(&threadPool.cond);
                pthread_mutex_unlock(&threadPool.mutex);
                for(int j = 0;j < threadPool.tidArr.workerNum;j++){
                    pthread_join(threadPool.tidArr.arr[j],NULL);
                }
                printf("thread pool has been exited!\n");
                exit(0);
            }
            else{
                // 处理各个客户端的短指令,处理完指令的fd要从原集合移除，放入新集合
                pushSet(&out,netfd,set_pointer);
            }
        }
        if(out.setNum[(set_pointer+1)%30] > 0){   // 超时返回，执行踢人逻辑,踢掉(set_pointer+1)%30集合内的所有fd
            int num = 0;
            int i = 0;
            while(num < out.setNum[(set_pointer+1)%30]){
                if(out.setArr[(set_pointer+1)%30][i] != -1){
                    close(out.setArr[(set_pointer+1)%30][i]);
                    num++;
                    continue;
                }
                i++;
            }
            out.setNum[(set_pointer+1)%30] = 0;
            memset(out.setArr[(set_pointer+1)%30],-1,sizeof(int)*MAX_SET_SIZE);
        }
    }
    close(sockfd);
    return 0;
}

